<template>
  <div class="max-w-full flex">
    <div class="mr-10px min-w-300px" v-if="treeData.length !== 0">
      <el-card shadow="never">
        <template #header>
          <span>资产列表</span>
        </template>
        <div class="min-h-300px">
          <ns-input placeholder="输入库表名称进行搜索" v-model="filterText" />
          <div class="flex">
            <el-tree
              style="flex: 1"
              ref="treeRef"
              :data="treeLsit"
              :props="defaultProps"
              @node-click="handleNodeClick"
              :filter-node-method="filterNode"
              class="mt-5px max-w-full"
              node-key="id"
              :default-expanded-keys="defaultExpandedKeys"
              @node-expand="nodeExpand"
              @node-collapse="nodeCollapse"
            />
            <el-icon v-if="showTreeIp" style="height: 36px; width: 36px">
              <Hide @click="showTreeIp = false" />
            </el-icon>
            <el-icon v-else style="height: 36px; width: 36px">
              <View @click="showTreeIp = true" />
            </el-icon>
          </div>
        </div>
      </el-card>
    </div>
    <div :style="{ width: treeData.length !== 0 ? 'calc(100% - 300px)' : '100%' }">
      <div>
        <el-card shadow="never">
          <!-- <template #header>
            <span>{{ currentSourceName }}</span>
          </template> -->
          <el-descriptions :column="infoOptions.column" v-show="showStatus === 'root'">
            <div v-for="(item, index) in infoOptions.columns" :key="index">
              <el-descriptions-item :label="item.label">
                <span
                  v-if="item.key == 'ip'"
                  style="
                    width: 14%;
                    display: inline-flex;
                    align-items: center;
                    justify-content: space-between;
                  "
                >
                  <span v-if="showDetailIp">
                    {{ infoOptions.data.ip }}:{{ infoOptions.data.port }}</span
                  >
                  <span v-else>***********</span>
                  <el-Icon v-if="showDetailIp">
                    <Hide @click="showDetailIp = false" />
                  </el-Icon>
                  <el-Icon v-else>
                    <View @click="showDetailIp = true" />
                  </el-Icon>
                </span>
                <span v-else-if="item.key == 'source'">
                  {{
                    sourceMap.has(infoOptions.data.source)
                      ? sourceMap.get(infoOptions.data.source)
                      : '--'
                  }}
                </span>
                <span v-else> {{ infoOptions.data[item.key] || '--' }}</span>
              </el-descriptions-item>
            </div>
          </el-descriptions>
          <div v-if="showStatus !== 'root'">
            <el-form label-width="100px" ref="formRef" :model="searchValue">
              <el-row>
                <el-col :span="6" v-if="showStatus === 'db' || showStatus === 'schema'">
                  <el-form-item label="表名称" prop="table">
                    <ns-input v-model="searchValue.table" clearable placeholder="请输入表名称" />
                  </el-form-item>
                </el-col>
                <el-col :span="6" v-if="showStatus === 'table'">
                  <el-form-item label="字段名称" prop="column">
                    <ns-input v-model="searchValue.column" clearable placeholder="请输入字段名称" />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item
                    :label="showStatus === 'db' || showStatus === 'schema' ? '表描述' : '字段描述'"
                    :prop="showStatus === 'db' || showStatus === 'schema' ? 'remark' : 'comment'"
                  >
                    <ns-input
                      v-model="
                        searchValue[
                          showStatus === 'db' || showStatus === 'schema' ? 'remark' : 'comment'
                        ]
                      "
                      clearable
                      :placeholder="`请输入${showStatus === 'db' || showStatus === 'schema' ? '表描述' : '字段描述'}`"
                    />
                  </el-form-item>
                </el-col>
                <!-- <el-col :span="6">
                  <el-form-item label="所属库" prop="database">
                    <ns-input v-model="searchValue.database" clearable placeholder="请输入所属库" />
                  </el-form-item>
                </el-col> -->
                <el-col :span="6" v-if="showStatus === 'table'">
                  <el-form-item label="所属表" prop="table">
                    <ns-input v-model="searchValue.table" clearable placeholder="请输入所属表" />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="重要程度" prop="importance">
                    <el-select
                      v-model="searchValue.importance"
                      clearable
                      placeholder="请选择重要程度"
                    >
                      <el-option label="重要数据" value="重要数据" key="1" />
                      <el-option label="公开数据" value="公开数据" key="0" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="分类" prop="classification">
                    <el-cascader
                      v-model="searchValue.classification"
                      placeholder="请选择分类"
                      :props="classificationCascaderProps"
                      :options="classificationList"
                      filterable
                      clearable
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="分级" prop="level">
                    <el-select v-model="searchValue.level" clearable placeholder="请选择分级">
                      <el-option
                        v-for="(level, levelIndex) in levelList"
                        :key="levelIndex"
                        :label="level.levelName"
                        :value="level.levelCode"
                      />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="是否已分级">
                    <el-select
                      v-model="searchValue.isLevel"
                      clearable
                      placeholder="请选择是否已分级"
                    >
                      <el-option label="已分级" :value="true" />
                      <el-option label="未分级" :value="false" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="24" class="text-right">
                  <el-button @click="search" type="primary">搜索</el-button>
                  <el-button @click="searchReset" plain>重置</el-button>
                </el-col>
              </el-row>
            </el-form>
            <el-divider />
            <el-button type="primary" :disabled="ids.length == 0" @click="handleUpdateList"
              >批量修改</el-button
            >
            <el-button plain @click="handleExport">导出</el-button>
            <el-button plain @click="handleImport">导入</el-button>
            <el-button
              plain
              @click="handleEditInfo(showStatus)"
              v-hasPermi="['pending:database:showInfo']"
              v-if="showStatus === 'table' || showStatus === 'db' || showStatus === 'schema'"
              >信息展示设置</el-button
            >
            <el-button
              plain
              @click="dialogVisible = true"
              v-if="
                (showStatus === 'table' || showStatus === 'db' || showStatus === 'schema') &&
                canAdd &&
                sourceType == 2
              "
              >新增</el-button
            >
            <AsyncTable
              class="mt-12px"
              ref="tableRef"
              :fetchData="fetchData"
              @selection-change="changeTable"
              v-bind="tableOptions"
            />
          </div>
        </el-card>
      </div>
    </div>
    <el-dialog
      title="新增"
      align-center
      :model-value="dialogVisible"
      v-if="dialogVisible"
      @close="cancle"
    >
      <el-form ref="addFormRef" :model="addFormInfo" label-suffix="：" label-width="100px">
        <template v-if="showStatus === 'db' || showStatus === 'schema'">
          <el-form-item
            label="表名称"
            prop="table"
            :rules="[{ required: true, trigger: 'blur', message: '请输入表名称' }]"
          >
            <ns-input placeholder="请输入表名称" clearable v-model="addFormInfo.table" />
          </el-form-item>
          <el-form-item label="表描述" prop="remark">
            <ns-input placeholder="请输入表描述" clearable v-model="addFormInfo.remark" />
          </el-form-item>
        </template>
        <template v-else>
          <el-form-item
            label="字段名称"
            prop="column"
            :rules="[{ required: true, trigger: 'blur', message: '请输入字段名称' }]"
          >
            <ns-input placeholder="请输入字段名称" clearable v-model="addFormInfo.column" />
          </el-form-item>
          <el-form-item label="字段描述" prop="comment">
            <ns-input placeholder="请输入字段描述" clearable v-model="addFormInfo.comment" />
          </el-form-item>
          <el-form-item label="抽样数据" prop="samples">
            <ns-input placeholder="请输入抽样数据" clearable v-model="addFormInfo.samples" />
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <el-button @click="cancle">取消</el-button>
        <el-button @click="addList" type="primary">确认</el-button>
      </template>
    </el-dialog>
    <InfoShow ref="dialogRef" @success="getInfoShowConf" :showQuery="false" />
    <!-- 批量修改分类分级弹窗 -->
    <UpdateListLevel ref="updateListRef" @success="search" />

    <ImportForm ref="importFormRef" @success="search" />
  </div>
</template>

<script setup lang="tsx">
import InfoShow from '@/views/assetManage/components/infoShow.vue'
import * as infoShowApi from '@/api/infoShow/index'
import { Hide, View } from '@element-plus/icons-vue'
import ImportForm from '@/views/asset/assetList/components/ImportForm.vue'
import { sourceMap } from '@/utils/dict'
import { DescriptionsProps } from '@/types/descriptions'
import { getAssetByLevel } from '@/api/assetDetail'
import {
  getDataSourceDetail,
  assetMessageExportExcel,
  assetDel,
  getDataBaseList,
  getAssetDetail,
  newAssetMessageExportExcel,
  addTableAndField
} from '@/api/assetList'
import { dataClassificationTree } from '@/api/dataStandards/classification/index'
import { levelPage } from '@/api/strategyManage/level/index'
import { getCurrentInstance } from 'vue'
import UpdateListLevel from './updateListLevel.vue'
import dayjs from 'dayjs'
import { cloneDeep, sample } from 'lodash-es'
import { renderSamples, renderClassification, renderLevel } from '@/utils/commonRender'
import download from '@/utils/download'

const addFormRef = ref()
const addFormInfo = ref({
  samples: '',
  column: '',
  remark: '',
  table: '',
  comment: ''
})
const parentInfo = ref({
  assetType: '',
  assetTypeName: '',
  batchNum: '',
  collectionAssetId: '',
  columnType: '',
  deptId: '',
  deptName: '',
  historyId: '',
  ip: '',
  parentId: '',
  port: '',
  schema: '',
  database: '',
  dataType: '',
  source: '',
  sysId: '',
  sysName: '',
  taskId: '',
  template: '',
  templateName: '',
  type: '',
  dataSourceId: ''
})
const router = useRouter()
const message = useMessage() // 消息弹窗
const route = useRoute()
const assetId = ref<string>(route.query.id as string)
const { proxy } = getCurrentInstance() as any
const showDetailIp = ref(false)
const showTreeIp = ref(false)
const dialogVisible = ref(false)
interface Tree {
  label: string
  children?: Tree[]
}
const classificationCascaderProps = ref({
  checkStrictly: true,
  label: 'text',
  value: 'id',
  children: 'children',
  emitPath: false
})

const props = defineProps({
  treeData: {
    type: Array,
    default: () => []
  },
  tableShow: {
    type: String
  },
  isList: {
    type: Boolean
  },
  canAdd: {
    default: false,
    type: Boolean || String
  },
  sourceType: {
    type: Number || String
  }
})

const emit = defineEmits(['tableSearch', 'renew'])
// 展示状态 root：数据源层级 db：数据库层级 table：表层级
const showStatus = ref('root')
const treeRef = ref()
const filterText = ref()
const currentSourceName = ref()
const defaultExpandedKeys = ref([])
const defaultProps = {
  children: 'children',
  label: 'showName'
}

const infoOptions: DescriptionsProps = reactive({
  column: 1,
  columns: [
    { label: '资产地址：', key: 'ip' },
    { label: '资产类型：', key: 'assetTypeName' },
    { label: '库名：', key: 'dbName' },
    { label: '数据来源：', key: 'source' },
    { label: '归属机构：', key: 'deptName' },
    { label: '归属系统：', key: 'sysName' }
  ],
  data: {}
})

const tableRef = ref()
const formRef = ref()
const ids = ref<string[]>([])
const tableOptions = reactive({
  columns: [
    { type: 'selection' },
    { label: '表名称', prop: 'table' },
    { label: '表描述', prop: 'remark' },
    // { label: '所属库', prop: 'database' },
    {
      label: '分类',
      render: renderClassification
    },
    {
      label: '分级',
      render: renderLevel
    },
    {
      label: '保密期限',
      prop: 'institutionFiled3',
      'min-width': '80px'
    },
    {
      label: '定密日期',
      prop: 'field1',
      'min-width': '80px'
    },
    {
      label: '解密日期',
      prop: 'field2',
      'min-width': '80px'
    },
    {
      label: '到期后变更等级',
      prop: 'deadlineLevelName',
      'min-width': '150px'
    },
    // {
    //   label: '重要程度',
    //   render: ({ row }) => {
    //     return (
    //       <>
    //         <span>{row.handImportance || row.importance || '--'}</span>
    //       </>
    //     )
    //   }
    // },
    {
      label: '操作',
      width: '150px',
      fixed: 'right',
      render: ({ row }) => {
        return (
          <>
            <el-button link type="primary" onClick={() => grade(row)}>
              编辑
            </el-button>
            <el-button link type="primary" onClick={() => handleHistory(row)}>
              历史记录
            </el-button>
          </>
        )
      }
    }
  ],
  data: []
})
const tableColumns = [
  {
    type: 'selection'
  },
  { label: '表名称', prop: 'table' },
  { label: '表描述', prop: 'remark' },
  {
    label: '分类',
    render: renderClassification
  },
  {
    label: '分级',
    render: renderLevel
  },
  {
    label: '保密期限',
    prop: 'institutionFiled3',
    'min-width': '80px'
  },
  {
    label: '定密日期',
    prop: 'field1',
    'min-width': '80px'
  },
  {
    label: '解密日期',
    prop: 'field2',
    'min-width': '80px'
  },
  {
    label: '到期后变更等级',
    prop: 'deadlineLevelName',
    'min-width': '150px'
  },
  {
    label: '操作',
    width: '190px',
    fixed: 'right',
    render: ({ row }) => {
      return (
        <>
          <el-button link type="primary" onClick={() => grade(row)}>
            编辑
          </el-button>
          <el-button link type="primary" onClick={() => handleHistory(row)}>
            历史记录
          </el-button>
          <ns-button
            style="margin-left:6px"
            link
            type="danger"
            confirm
            onClick={() => {
              del(row)
            }}
          >
            删除
          </ns-button>
        </>
      )
    }
  }
]
const filedColumns = [
  {
    type: 'selection'
  },
  { label: '字段名称', prop: 'column', 'min-width': '100px' },
  { label: '字段描述', prop: 'comment', 'min-width': '100px' },
  {
    label: '抽样数据',
    render: renderSamples,
    width: '200px',
    isShowOverflowTooltip: 'false'
  },
  {
    label: '分类',
    render: renderClassification
  },
  {
    label: '分级',
    render: renderLevel
  },
  {
    label: '保密期限',
    prop: 'institutionFiled3',
    'min-width': '100px'
  },
  {
    label: '定密日期',
    prop: 'field1',
    'min-width': '100px'
  },
  {
    label: '解密日期',
    prop: 'field2',
    'min-width': '100px'
  },
  {
    label: '到期后变更等级',
    prop: 'deadlineLevelName',
    'min-width': '150px'
  },
  {
    label: '操作',
    width: '190px',
    fixed: 'right',
    render: ({ row }) => {
      return (
        <>
          <el-button link type="primary" onClick={() => grade(row)}>
            编辑
          </el-button>
          <el-button link type="primary" onClick={() => handleHistory(row)}>
            历史记录
          </el-button>
          <ns-button
            style="margin-left:6px"
            link
            type="danger"
            confirm
            onClick={() => {
              del(row)
            }}
          >
            删除
          </ns-button>
        </>
      )
    }
  }
]

const nodeCollapse = (data) => {
  defaultExpandedKeys.value = defaultExpandedKeys.value.filter((item) => {
    return data.id != item
  })
}
const nodeExpand = (data) => {
  defaultExpandedKeys.value.push(data.id)
}

const searchValue = ref({
  parentId: '',
  column: '', //字段名
  table: '', //表名称|所属表
  comment: '', //描述
  database: '', //所属库
  importance: '', //重要程度
  classification: '', //分类
  level: '', //分级
  remark: '',
  isLevel: ''
})

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

const del = (row) => {
  assetDel(row.id).then((response) => {
    tableRef.value.fetchData()
    ElMessage.success('删除成功')
  })
}

const changeTable = (val) => {
  ids.value = []
  val.map((item) => {
    ids.value.push(item.id)
  })
}

// 搜索重置
const searchReset = () => {
  formRef.value.resetFields()
  tableRef.value?.fetchData()
  tableRef.value?.resetPage()
}
// 搜索
const search = () => {
  tableRef.value?.fetchData()
  tableRef.value?.resetPage()
}

const pageParams = ref({
  page: 1,
  pageSize: 10
})

const addList = () => {
  if (showStatus.value === 'db' || showStatus.value === 'schema') {
    parentInfo.value.dataType = 'table'
  } else {
    parentInfo.value.dataType = 'column'
  }
  addTableAndField([
    {
      ...parentInfo.value,
      ...addFormInfo.value
    }
  ]).then((res) => {
    if (res) {
      dialogVisible.value = false
      ElMessage.success('新增成功')
      tableRef.value?.resetPage()
      tableRef.value?.fetchData()
      addFormRef.value.resetFields()
      emit('renew')
    }
  })
}
const cancle = () => {
  dialogVisible.value = false
  addFormRef.value.resetFields()
}
// 表格数据获取
const fetchData = async ({ page, pageSize }) => {
  pageParams.value = {
    page,
    pageSize
  }
  // 1.数量统计
  emit('tableSearch', searchValue.value)
  // 2.表格数据更新
  let params
  let apiInterface
  if (props.tableShow === 'field' || props.tableShow === 'table') {
    params = {
      page,
      pageSize,
      ...searchValue.value,
      dataSourceId: assetId.value,
      dataType: props.tableShow === 'field' ? 'column' : 'table'
    }
    apiInterface = getAssetByLevel
  } else {
    params = {
      page,
      pageSize,
      ...searchValue.value
    }
    apiInterface = getDataBaseList
  }
  const { data, count } = await apiInterface(params)
  console.log(data, 666666)

  return { data, count }
}
//
const updateTableData = () => {
  tableRef.value?.fetchData()
}

const filterNode = (value: string, data) => {
  if (!value) return true
  return data.showName.includes(value)
}

const handleNodeClick = async (data) => {
  currentSourceName.value = data?.showName

  if (data.children.length > 0 && data.children[0].dataType == 'schema' && data.dataType === 'db') {
    return
  }
  showStatus.value = data.dataType
  searchValue.value.parentId = data.id
  const cunrrentInfo = await getAssetDetail({ id: data.id })
  Object.keys(parentInfo.value).forEach((item) => {
    parentInfo.value[item] = cunrrentInfo?.data[item]
  })
  parentInfo.value.parentId = data.id
  if (data.dataType === 'db' || data.dataType === 'schema') {
    tableOptions.columns = []
    nextTick(() => {
      tableOptions.columns = tableColumns
      tableRef.value?.fetchData()
    })
  } else if (data.dataType === 'table') {
    tableOptions.columns = []
    nextTick(() => {
      tableOptions.columns = filedColumns
      getInfoShowConf()
      tableRef.value?.fetchData()
    })
  }
}

const getDetail = async () => {
  const { data } = await getDataSourceDetail({ id: assetId.value })
  infoOptions.data = data
}

// 分级分类（行）
const grade = (row) => {
  proxy?.$Drawer({
    params: {
      ...row,
      type: row.handClassificationName ? `人工` : row.classificationName ? `自动` : '--',
      callBack: () => {
        tableRef.value?.fetchData()
        tableRef.value?.resetPage()
      }
    },
    title: `分级分类`,
    size: '40%',
    component: import('./grade.vue')
  })
}

// 历史记录
const handleHistory = (row) => {
  router.push({
    path: '/assetManage/fileHistory',
    query: {
      id: row.id,
      dataType: props.tableShow === 'field' ? 'column' : 'table'
    }
  })
}

// 批量修改
const updateListRef = ref()
const handleUpdateList = () => {
  updateListRef.value.open(ids.value)
}

const exportLoading = ref(true)
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    let params
    if (props.tableShow === 'field' || props.tableShow === 'table') {
      params = {
        ...pageParams.value,
        ...searchValue.value,
        dataSourceId: assetId.value,
        dataType: props.tableShow === 'field' ? 'column' : 'table',
        exportType: showStatus.value === 'db' || showStatus.value === 'schema' ? 'column' : 'table'
      }
    } else {
      params = {
        ...pageParams.value,
        ...searchValue.value,
        ids: ids.value,
        exportType: showStatus.value === 'db' || showStatus.value === 'schema' ? 'table' : 'column'
      }
    }
    const data = await newAssetMessageExportExcel(params)
    download.excel(data, '分级结果.xlsx')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

const importFormRef = ref()
const handleImport = () => {
  importFormRef.value.open()
}

/** 添加/修改操作 */
const dialogRef = ref()
const handleEditInfo = (showStatus) => {
  dialogRef.value.open(showStatus == 'table' ? '10' : '99')
}

// 获取信息展示
const infoShowList = ref()
const getInfoShowConf = async () => {
  const data = await infoShowApi.infoShowList({
    type: showStatus.value == 'table' ? '10' : '99',
    language: location.href.indexOf('/en/') >= 0 ? 'en' : ''
  })
  infoShowList.value = data
  data.forEach((item, index) => {
    tableOptions.columns[index + 1].hide = item.show === 0 ? true : false
  })
}
const treeLsit = ref([])

watch(
  () => props.isList,
  () => {
    if (props.treeData.length > 0) {
      treeLsit.value = cloneDeep(props.treeData)
      if (treeLsit.value.length > 0) {
        treeLsit.value[0].showName = `${showTreeIp.value ? props.treeData[0]?.showName : '***********'}`
      }
    }
  },
  { immediate: true }
)
watch(props, () => {
  treeLsit.value = cloneDeep(props.treeData)
  if (treeLsit.value.length > 0) {
    treeLsit.value[0].showName = `${showTreeIp.value ? props.treeData[0]?.showName : '***********'}`
  }
})
const classificationList = ref([])
const getClassificationList = async () => {
  const data = await dataClassificationTree({ type: 1 })
  classificationList.value = traverseTree(data)
}
function traverseTree(data) {
  const updatedTree = []
  for (let i = 0; i < data.length; i++) {
    const node = data[i] // 创建新节点并添加 disable 属性
    if (node.pid == '-1') {
      node.disabled = true
    }
    updatedTree.push(node)
    if (node.children && node.children.length > 0) {
      node.children = traverseTree(node.children) // 递归遍历子节点并更新子树结构
    }
  }
  return updatedTree
}

const levelList = ref([])
const getLevelList = async () => {
  const { data } = await levelPage({ page: 1, pageSize: 999 })
  console.log('data', data)
  levelList.value = data
}
onMounted(() => {
  getLevelList()
  getClassificationList()
  getDetail()
  if (props.tableShow === 'field') {
    showStatus.value = 'table'
    tableOptions.columns = filedColumns
    getInfoShowConf()
    tableRef.value?.fetchData()
  } else if (props.tableShow === 'table') {
    showStatus.value = 'db'
    tableOptions.columns = tableColumns
    tableRef.value?.fetchData()
  }
})

watch(showTreeIp, (newVal) => {
  if (treeLsit.value.length > 0) {
    treeLsit.value[0].showName = `${showTreeIp.value ? props.treeData[0]?.showName : '***********'}`
  }
})
defineExpose({ search, getDetail })
</script>
<style lang="scss" scoped>
::v-deep .el-descriptions__table {
  width: 100%;
}
</style>
